package com.ruoyi.user.service.thirdpay.alipay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.user.service.thirdpay.AbstractPayService;
import com.ruoyi.user.service.thirdpay.alipay.requestparams.AlipayRefundParams;
import com.ruoyi.user.service.thirdpay.alipay.requestparams.AlipayRefundQueryParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
 * 支付宝支付服务实现
 * 提供支付宝扫码支付、退款、查询等相关功能
 *
 * @author houyong
 */
@Service
@RefreshScope
public class AlipayService extends AbstractPayService {
    private final Logger logger = Logger.getLogger(AlipayService.class.getName());

    @Value("${alipay.charset}")
    private String charset;

    @Value("${alipay.alipayPublicKey}")
    private String alipayPublicKey;

    @Value("${alipay.signtype}")
    private String signType;

    @Value("${alipay.notice.url}")
    private String notifyURL;

    @Autowired
    private AlipayClient alipayClient;

    /**
     * 生成支付宝付款码,使用支付宝扫码进行支付
     *
     * @param orderId  订单ID
     * @param totalFee 总金额
     * @param subject  商品标题
     * @param body     商品描述
     * @return 支付二维码链接
     * @throws AlipayApiException 支付宝API异常
     */
    public AjaxResult getAlipayOrderChargeForScanQrCode(String orderId, String totalFee, String subject, String body)
            throws AlipayApiException {
        // 构造请求参数以调用接口
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl(notifyURL);
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        // 设置订单标题
        model.setSubject(subject);
        // 设置订单附加信息
        model.setBody(body);
        // 设置商户订单号
        model.setOutTradeNo(orderId);
        // 设置订单总金额
        model.setTotalAmount(totalFee);
        request.setBizModel(model);
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        logger.info("扫码支付结果===>" + JSON.toJSONString(response));

        if (response.isSuccess()) {
            logger.info("调用成功");
            return AjaxResult.success(response.getQrCode());
        } else {
            return AjaxResult.error("获取支付宝扫码支付二维码失败，请刷新后重试");
        }
    }

    /**
     * 验证支付宝回调签名
     *
     * @param paramsMap 回调参数
     * @return 签名是否有效
     * @throws AlipayApiException 支付宝API异常
     */
    public boolean checksignVerified(Map<String, String> paramsMap) throws AlipayApiException {
        boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, alipayPublicKey, charset, signType); //调用SDK验证签名
        return signVerified;
    }

    /**
     * 查询支付宝退款结果
     *
     * @param orderId      商户订单号
     * @param outRequestNo 退款请求号
     * @return 退款查询响应
     * @throws AlipayApiException 支付宝API异常
     */
    public AlipayTradeFastpayRefundQueryResponse searchAliPayRefundResult(String orderId, String outRequestNo) throws AlipayApiException {
        AlipayTradeFastpayRefundQueryRequest searchRefundRequest = new AlipayTradeFastpayRefundQueryRequest();
        AlipayRefundQueryParams refundQueryParams = new AlipayRefundQueryParams(orderId, outRequestNo);
        searchRefundRequest.setBizContent(JSON.toJSONString(refundQueryParams));
        AlipayTradeFastpayRefundQueryResponse refundResponse = alipayClient.execute(searchRefundRequest);
        return refundResponse;
    }

    /**
     * 支付宝退款请求
     *
     * @param outRequestNo 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传 退款标识号
     * @param orderId      商户订单号
     * @param amount       退款金额
     * @param refundDesc   退款描述
     * @return 退款响应
     * @throws AlipayApiException 支付宝API异常
     */
    public AlipayTradeRefundResponse alipayRefund(String outRequestNo, String orderId, String amount, String refundDesc) throws AlipayApiException {
        AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
        AlipayRefundParams alipayRefundParams = new AlipayRefundParams(outRequestNo, orderId, amount, refundDesc);
        refundRequest.setBizContent(JSON.toJSONString(alipayRefundParams));
        AlipayTradeRefundResponse refundResponse = alipayClient.execute(refundRequest);
        return refundResponse;
    }

    /**
     * 统一收单线下交易查询
     *
     * @param orderId 商户订单号
     * @param tradeNo 支付宝交易号
     * @return 交易查询响应
     * @throws AlipayApiException 支付宝API异常
     */
    public AlipayTradeQueryResponse alipayTradeQuery(String orderId, String tradeNo) throws AlipayApiException {
        AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
        Map<String, String> map = new HashMap<>();
        if (!StringUtils.isEmpty(orderId)) {
            map.put("out_trade_no", orderId);
        }
        if (!StringUtils.isEmpty(tradeNo)) {
            map.put("trade_no", tradeNo);
        }
        alipayTradeQueryRequest.setBizContent(JSON.toJSONString(map));
        AlipayTradeQueryResponse response = alipayClient.execute(alipayTradeQueryRequest);
        return response;
    }
}
